﻿using HARTCalibrationTool.SerialPortManager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Threading.Tasks;
using static HARTCalibrationTool.Commands.HART.CustomCommands.CustomCommandsBase;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace HARTCalibrationTool.Commands.HART
{
    public class HART35WritePVRangeValues : HARTCMDsBase
    {
        private byte _unit;
        private float _upRge;
        private float _downRge;

        public HART35WritePVRangeValues(SerialPortsBase serialPortManager, string commandName, byte unit, float upRge, float downRge) : base(serialPortManager, commandName)
        {
            _unit = unit;
            _upRge = upRge;
            _downRge = downRge;

            _stHARTCMDsStruct = new HARTCMDsCodeStruct()
            {
                preamble = new byte[5] { 0xff, 0xff, 0xff, 0xff, 0xff },
                start = 0x82,
                addressByte1 = 0xA2,
                addressByte2 = 0x82,
                addressByte3 = 0x74,
                addressByte4 = 0x2E,
                addressByte5 = 0x96,
                cmdID = 0x23,
                size = 0x09,
                parity = 0xFF,
            };
        }

        protected override async Task SendCMD()
        {
            List<byte> byteList = new List<byte>();
            byte[] upperRge = new byte[4];
            byte[] lowerRge = new byte[4];
            byte[] tempData = new byte[32];
            byte[] cmdCode = new byte[32];
            byte[] deviceID = GetDeviceID();

            if ((deviceID[0] == 0x00) && (deviceID[1] == 0x00) && (deviceID[2] == 0x00))
            {
                SerialPortsBase.PrintMessage("通道" + Utils.CountTrailingZeros((uint)GetCMDsChannelID()).ToString() + ", Device ID 错误！");
                return;
            }

            _stHARTCMDsStruct.addressByte3 = deviceID[0];
            _stHARTCMDsStruct.addressByte4 = deviceID[1];
            _stHARTCMDsStruct.addressByte5 = deviceID[2];

            byteList.AddRange(_stHARTCMDsStruct.preamble);
            byteList.Add(_stHARTCMDsStruct.start);
            byteList.Add(_stHARTCMDsStruct.addressByte1);
            byteList.Add(_stHARTCMDsStruct.addressByte2);
            byteList.Add(_stHARTCMDsStruct.addressByte3);
            byteList.Add(_stHARTCMDsStruct.addressByte4);
            byteList.Add(_stHARTCMDsStruct.addressByte5);
            byteList.Add(_stHARTCMDsStruct.cmdID);
            byteList.Add(_stHARTCMDsStruct.size);
            byteList.Add(_unit);

            upperRge = BitConverter.GetBytes(_upRge);
            lowerRge = BitConverter.GetBytes(_downRge);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(upperRge);
                Array.Reverse(lowerRge);
            }

            byteList.AddRange(upperRge);
            byteList.AddRange(lowerRge);

            byte[] bytes = byteList.ToArray();
            Array.Copy(bytes, 5, tempData, 0, bytes.Length - 5);
            _stHARTCMDsStruct.parity = Utils.GetHARTCRC(tempData, (byte)(bytes.Length - 5));

            byteList.Add(_stHARTCMDsStruct.parity);

            cmdCode = byteList.ToArray();

            SerialPortsBase.PrintMessage("--> " + Utils.HexToString(cmdCode));

            await SerialPortMager.SerialPortWrite(cmdCode);
        }

        public override async Task ParseResponse(byte[] data)
        {
            await Task.Run(() =>
            {
                SerialPortsBase.PrintMessage("<-- " + $"{Utils.HexToString(data)}");
            });
        }

        public override void OnFailure()
        {

        }

        public override void OnSuccess()
        {

        }

        public override void OnTimeout()
        {

        }
    }
}
